#include "cyclelist.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"

/**
 * 功 能：
 *      创建一个链表
 * 参 数：
 *      无
 * 返回值：
 *      成功：操作句柄
 *      失败：NULL
 **/
Cyclelist *Cyclelist_create()
{
    TCyclelist *ret = (TCyclelist *)malloc(sizeof(TCyclelist));
    if (ret == NULL)
        return NULL;
    // memset(ret, 0, sizeof(TCyclelist));
    ret->length = 0;
    ret->slider = NULL;
    ret->header.next = NULL;

    return ret;
}
/**
 * 功 能：
 *      销毁一个链表
 * 参 数：
 *      list：要操作的链表
 * 返回值：
 *      成功：0
 *      失败：-1
 **/
int Cyclelist_destory(Cyclelist **list)
{
    if (list != NULL)
    {
        free(*list);
        *list = NULL;
        return 0;
    }
    return -1;
}

/**
 * 功 能：
 *      清除一个链表, 使得链表恢复到初始状态
 * 参 数：
 *      list：要操作的链表
 * 返回值：
 *      成功：0
 *      失败：-1
 **/
int Cyclelist_clear(Cyclelist *list)
{
    TCyclelist *slist = (TCyclelist *)list;
    if (slist == NULL)
        return -1;
    slist->length = 0;
    slist->header.next = NULL;
    slist->slider = NULL;

    return 0;
}

/**
 * 功 能：
 *      获取链表长度
 * 参 数：
 *      list：要操作的链表
 * 返回值：
 *      成功：链表的长度
 *      失败：-1
 **/
int Cyclelist_Length(Cyclelist *list)
{
    TCyclelist *slist = NULL;
    if (list == NULL)
        return -1;
    slist = (TCyclelist *)list;
    return slist->length;
}
/**
 * 功 能：
 *      获取指定位置的元素
 * 参 数：
 *      list：要操作的链表
 *      pos ：要获取元素的位置
 * 返回值：
 *      成功：节点的首地址
 *      失败：NULL
 **/
CyclelistNode *Cyclelist_Get(Cyclelist *list, int pos)
{
    int i = 0;
    TCyclelist *slist = NULL;
    CyclelistNode *current = NULL;
    if (pos < 0 || list == NULL)
        return NULL;
    slist = (TCyclelist *)list;
    // 从循环链表的角度来说，pos的值只要是大于0的应该都是合法的
    // 你品，你细品
    // if (pos > slist->length)
    //     pos = slist->length;
    // 让辅助指针变量指向链表的头部
    // current = &(slist->header);
    current = (CyclelistNode *)slist;

    while (i < pos && current->next != NULL)
    {
        i++;
        current = current->next;
    }
    // for(i = 0; i < pos; i++)
    // {
    //     current = current->next;
    // }
    return current->next;
}
/**
 * 功 能：
 *      在指定的位置插入一个元素
 * 参 数：
 *      list：要操作的链表
 *      node：要插入的节点
 *      pos ：要插入的位置
 * 返回值：
 *      成功：0
 *      失败：-1
 **/
int Cyclelist_insert(Cyclelist *list, CyclelistNode *node, int pos)
{
    int i = 0;
    TCyclelist *slist = NULL;
    /* 参数判断 */
    if (list == NULL || node == NULL || pos < 0)
        return -1;
    /* 参数判断并矫正 */
    slist = (TCyclelist *)list;
    if (pos > slist->length)
        pos = slist->length;

    /* 下面两个个语句实现的效果一致 */
    // CyclelistNode *current = &(slist->header);
    CyclelistNode *current = (CyclelistNode *)slist;
    i = 0;
    while (i < pos && current->next != NULL)
    {
        i++;
        current = current->next;
    }
    // 让node链接后续的节点
    node->next = current->next;
    // 让前面的链表链接新的node节点
    current->next = node;

    // 如果是第一次插入元素
    if (slist->length == 0)
    {
        slist->slider = node;
        // node->next = node;
    }

    // 让长度自加一
    slist->length++;

    // 如果是头插法，则current还是指向头部
    // 如果链表是初始的状态，即只有头节点，没有其他的任何业务节点，那么
    // 最后一个节点也是第一个节点，还需要下面的操作吗，你品，你细品。
    if (current == (CyclelistNode *)slist && slist->length > 0)
    {
        // 获取最后一个节点
        CyclelistNode *last = Cyclelist_Get(slist, slist->length - 1);
        last->next = current->next;
    }
    return 0;
}

/**
 * 功 能：
 *      从指定的位置删除一个元素
 * 参 数：
 *      list：要操作的链表
 *      pos ：要删除元素的位置
 * 返回值：
 *      成功：删除节点的首地址
 *      失败：NULL
 **/
CyclelistNode *Cyclelist_delete(Cyclelist *list, int pos)
{
    int i = 0;
    TCyclelist *slist = (TCyclelist *)list;
    CyclelistNode *current = NULL, *ret = NULL;
    CyclelistNode *last = NULL;
    if (list == NULL || pos < 0 || slist->length < 1)
        return NULL;

    if (pos > slist->length)
        pos = slist->length;

    // current = &(slist->header);
    current = (CyclelistNode *)slist;

    while (i < pos && current->next != NULL)
    {
        i++;
        current = current->next;
    }
    // for(i = 0; i < pos; i++)
    // {
    //     current = current->next;
    // }
    // 若删除头节点
    if (current == (CyclelistNode *)slist)
    {
        last = (CyclelistNode *)Cyclelist_Get(slist, slist->length - 1);
    }
    // 缓存被删除的节点位置
    ret = current->next;
    // 连线，跳过要删除的节点
    current->next = ret->next;
    // 长度自减一
    slist->length--;

    // 判断链表是否为空
    if (last != NULL)
    {
        slist->header.next = ret->next;
        last->next = ret->next;
    }
    // 若删除元素为游标所指的元素
    if (slist->slider == ret)
    {
        slist->slider = ret->next;
    }
    // 如果删除元素后，链表长度为0
    if (slist->length == 0)
    {
        slist->header.next = NULL;
        slist->slider = NULL;
    }

    return ret; //将删除的节点的地址返回，让调用者析构这个内存
}

/**
 * 功 能：
 *      删除一个指定的元素
 * 参 数：
 *      list：要操作的链表
 *      node：要删除元素
 * 返回值：
 *      成功：删除节点的首地址
 *      失败：NULL
 **/
CyclelistNode *Cyclelist_deleteNode(Cyclelist *list, CyclelistNode *node)
{
    TCyclelist *slist = (TCyclelist *)list;
    CyclelistNode *ret = NULL;
    int i = 0;
    if (slist == NULL || node == NULL)
        return NULL;

    CyclelistNode *current = (CyclelistNode *)slist;
    // 查找node在链表中的位置
    for (i = 0; i < slist->length; i++)
    {
        if (current->next == node)
        {
            ret = current->next;
            break;
        }
        current = current->next;
    }
    //  如果ret 找到，根据 循环变量 i 去删除节点
    if (ret != NULL)
    {
        Cyclelist_delete(slist, i);
    }

    return ret;
}
/**
 * 功 能：
 *      将游标复位
 * 参 数：
 *      list：要操作的链表
 * 返回值：
 *      成功：复位之后的游标的值
 *      失败：NULL
 **/
CyclelistNode *Cyclelist_Reset(Cyclelist *list)
{
    TCyclelist *slist = (TCyclelist *)list;
    if (slist == NULL)
        return NULL;
    slist->slider = slist->header.next;

    return slist->slider;
}
/**
 * 功 能：
 *      获取当前游标的值
 * 参 数：
 *      list：要操作的链表
 * 返回值：
 *      成功：当前游标的值
 *      失败：NULL
 **/
CyclelistNode *Cyclelist_Current(Cyclelist *list)
{
    TCyclelist *slist = (TCyclelist *)list;
    // TCyclelist *ret = NULL;
    if (slist == NULL)
        return NULL;

    // ret = slist->slider;
    return slist->slider;
}
/**
 * 功 能：
 *      将游标后移，指向链表中下一个节点
 *      返回当前游标的值
 * 参 数：
 *      list：要操作的链表
 * 返回值：
 *      成功：当前游标的值
 *      失败：NULL
 **/
CyclelistNode *Cyclelist_Next(Cyclelist *list)
{
    TCyclelist *slist = (TCyclelist *)list;
    CyclelistNode *ret = NULL;
    
    if (slist == NULL || slist->slider == NULL)
        return NULL;
    
    ret = slist->slider;
    slist->slider = ret->next;
    
    return ret;
}

func_cyclelist fun_cyclelist = {
    Cyclelist_create,
    Cyclelist_destory,
    Cyclelist_clear,
    Cyclelist_Length,
    Cyclelist_insert,
    Cyclelist_Get,
    Cyclelist_delete,
    Cyclelist_deleteNode,
    Cyclelist_Reset,
    Cyclelist_Current,
    Cyclelist_Next
};
